--doc see http://wiki.nginx.org/HttpCoreModule#.24uri

-- 不需要认证的链接
local tabException = {
    "/index.php"
}

local tabBlock = {
    "/finance/back/pay",
}



-- 直接屏蔽的guid
local blocks = {
    "bc0113cee17f3df530f3e1c9d2ff7d5d"
}

-- 加密秘钥
local secret = "f30371feec4b4433cf2bcab252ab8ce2"

local secreta = "68a89d8873042851262b69a61ae4fc57"

function is_include(value, tabi)
    for k,v in ipairs(tabi) do
        if v == value then
            return true
        end
    end
    return false
end

function catch(what)
   return what[1]
end

function try(what)
   status, result = pcall(what[1])
   if not status then
      what[2](result)
   end
   return result
end


function check()
    local ok = nil
    local pid = nil
    local sig = nil
    local doc = nil
    local timestamp = 0

    local req_method = ngx.var.request_method
    local expire_time = 60 * 30

    --
    -- local secret = "821l1i1x3fv8vs3dxlj1v2x91jqfs3om"
    --
    -- heydo gen secret key for client auth
    local args = ngx.req.get_uri_args()

    -- Get auth params
    if req_method == "GET" then
        pid = ngx.var.arg_pid
        sig = ngx.var.arg__s_
        timestamp = ngx.var.arg__t_
        doc = ngx.var.arg_doc
    elseif  req_method == "POST" or req_method == "PUT" or  req_method == "DELETE" then
        try {
            function()
                ngx.req.read_body()
                local post_args = ngx.req.get_post_args()
                args = post_args
                pid = post_args.pid
                sig = post_args._s_
                timestamp = post_args._t_
                doc = post_args.doc
            end,
            catch {
                function(error)

                end
            }
        }

        if not sig then
            sig=ngx.var.arg__s_
        end

        if not timestamp then
            timestamp = ngx.var.arg__t_
        end

        if not doc then
            doc = ngx.var.arg_doc
        end


    else
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end

    -- ***** doc debug *****
    if doc then
        return
    end

    if not timestamp or timestamp == ""  then
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end

    if not sig or sig == "" then
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end


    local filter_args = ""
    local key_table = {}
    --取出所有的键
    for key,_ in pairs(args) do
        table.insert(key_table,key)
    end
    --对所有键进行排序
    table.sort(key_table)
    for _,key in pairs(key_table) do
        if key ~= "_s_"  and key ~= "_t_"  then
            filter_args = filter_args .. key .. "=" ..args[key]
        end
    end

    -- args =
    -- local filter_args, n, err = ngx.re.sub(args, "(&|\\?)_s_=[^&]*&?", "")
    -- if filter_args then
    -- else
    --     filter_args = args
    -- end

    -- local new_filter_args, nn, eerr = ngx.re.sub(filter_args, "(&|\\?)_t_=[^&]*&?", "")
    -- if new_filter_args then
    --     filter_args = new_filter_args
    -- else
    --     if not filter_args then
    --         filter_args = args
    --     end
    -- end
    --
    -- ngx.log(ngx.ERR, ngx.var.uri)
    -- ngx.log(ngx.ERR, filter_args)



    for _, value in pairs(blocks) do
        block = string.match(filter_args,value)
        if block then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end
    end

    -- the request is expired
    if ngx.now() - timestamp < -expire_time or ngx.now() - timestamp >= expire_time then
        ngx.status = ngx.HTTP_GONE
        local _now = ngx.now()
        ngx.header.server_time = _now
        ngx.say(_now)
        ngx.exit(ngx.HTTP_OK)
    end

    -- generate signature
    token_string = req_method .. ":" .. ngx.var.uri .. ":" .. filter_args .. ":" .. timestamp .. ":"  .. secret

    --ngx.log(ngx.ERR, token_string)
    token = ngx.md5(token_string)

    -- generate signature
    tokena_string = req_method .. ":" .. ngx.var.uri .. ":" .. filter_args .. ":" .. timestamp .. ":"  .. secreta

    --ngx.log(ngx.ERR, token_string)
    tokena = ngx.md5(tokena_string)

    -- ngx.log(ngx.ERR, token)

    -- Compare sever genned sig(var token) with request sig(request param sig)
    if token ~= sig then
        if tokena ~= sig then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end
    end
end

local is_block = is_include(ngx.var.uri, tabBlock)
if is_block then
    ngx.exit(ngx.HTTP_NOT_ALLOWED)
end

local is_exist = is_include(ngx.var.uri, tabException)

if not is_exist then
    -- check()
end